package com.websocet.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.websocet.domain.TreeNode;
import com.websocet.service.impl.TreeBuild;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: 陈玉鹏
 * @Description: TODO
 * @DateTime: 2023/2/13 20:51
 */
@RestController
public class TreeNodeController {

    @PostMapping("/testnull")
    public Integer tesstnull(@RequestBody TreeNode treeNode) {

        return treeNode.getId();
    }

    @GetMapping("/testnull")
    public String tesstnull2(String id) {

        return id;
    }

    @RequestMapping("/tree")
    public List<TreeNode> contextLoads() {

        // 模拟测试数据（通常为数据库的查询结果）
        List<TreeNode> treeNodeList = new ArrayList<>();
        treeNodeList.add(new TreeNode(1, 0, "顶级节点A"));
        treeNodeList.add(new TreeNode(2, 0, "顶级节点B"));
        treeNodeList.add(new TreeNode(3, 1, "父节点是A"));
        treeNodeList.add(new TreeNode(4, 3, "父节点是B"));
        treeNodeList.add(new TreeNode(5, 2, "父节点是B"));
        treeNodeList.add(new TreeNode(6, 3, "父节点的ID是3"));

        // 创建树形结构（数据集合作为参数）
        TreeBuild treeBuild = new TreeBuild(treeNodeList);
        // 原查询结果转换树形结构
        treeNodeList = treeBuild.buildTree();
        return treeNodeList;
    }

    @RequestMapping("/stream-tree")
    public List<TreeNode> contextLoads1() {

        // 模拟测试数据（通常为数据库的查询结果）
        List<TreeNode> treeNodeList = new ArrayList<>();
        treeNodeList.add(new TreeNode(1, 0, "顶级节点A"));
        treeNodeList.add(new TreeNode(2, 0, "顶级节点B"));
        treeNodeList.add(new TreeNode(3, 1, "父节点是A"));
        treeNodeList.add(new TreeNode(4, 3, "父节点是B"));
        treeNodeList.add(new TreeNode(5, 2, "父节点是B"));
        treeNodeList.add(new TreeNode(6, 3, "父节点的ID是3"));
        List<TreeNode> collect = treeNodeList.stream().filter(m -> m.getParentId() == 0).map(
                (m) -> {
                    m.setChildren(getChildrenList(m, treeNodeList));
                    return m;
                }
        ).collect(Collectors.toList());

        return collect;
    }

    /**
     * 获取子节点列表
     *
     * @param tree
     * @param list
     * @return
     */
    public static List<TreeNode> getChildrenList(TreeNode tree, List<TreeNode> list) {
        // 解释下面代码

        List<TreeNode> children = list.stream().filter(item -> Objects.equals(item.getParentId(), tree.getId())).map(
                (item) -> {
                    item.setChildren(getChildrenList(item, list));
                    return item;
                }
        ).collect(Collectors.toList());
        return children;
    }

    @RequestMapping("/total-tree")
    public Set<TreeNode> contextLoadsToeal() {
        //定义baseTree和treeToMerge
        List<TreeNode> baseTree = Arrays.asList(
                new TreeNode(1, 0, "顶级节点A"),
                new TreeNode(2, 0, "父节点是A"),
                new TreeNode(3, 1, "父节点是B"),
                new TreeNode(4, 1, "父节点的ID是3"),
                new TreeNode(5, 2, "父节点是A"),
                new TreeNode(6, 5, "父节点是B"),
                new TreeNode(7, 6, "父节点的ID是3")
        );
        TreeNode 父节点是A = new TreeNode(7, 6, "父节点是A");
        Set<TreeNode> deptUpList = getDeptUpList(baseTree, 父节点是A);
        return deptUpList;
    }

    /**
     * 获取传入节点的上级所有节点
     *
     * @param deptAll
     * @param leafNodeDept
     * @return
     */
    public static Set<TreeNode> getDeptUpList(List<TreeNode> deptAll, TreeNode leafNodeDept) {
        if (!ObjectUtils.isEmpty(leafNodeDept)) {
            Set<TreeNode> set = new HashSet<>();
            Integer parentId = leafNodeDept.getParentId();
            List<TreeNode> parentDepts = deptAll.stream().filter(item -> item.getId().equals(parentId)).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(parentDepts)) {
                TreeNode parentDept = parentDepts.get(0);
                set.add(parentDept);
                Set<TreeNode> deptUpTree = getDeptUpList(deptAll, parentDept);
                if (deptUpTree != null) {
                    set.addAll(deptUpTree);
                }
                return set;
            }
        }
        return null;
    }

    @RequestMapping("/filter-tree")
    public List<TreeNode> contextLoadsToealFilter() {
        //定义baseTree和treeToMerge
        List<TreeNode> baseTree = Arrays.asList(
                new TreeNode(1, 0, "顶级节点A"),
                new TreeNode(2, 0, "父节点是A"),
                new TreeNode(3, 1, "父节点是B"),
                new TreeNode(4, 1, "父节点的ID是3"),
                new TreeNode(5, 2, "父节点是A"),
                new TreeNode(6, 5, "父节点是B"),
                new TreeNode(7, 6, "父节点的ID是3")
        );


//        return builderTree(baseTree);
        return buildDeptTreeByStream(baseTree);

    }


    // 法一
    public static List<TreeNode> buildDeptTreeByStream(List<TreeNode> trees) {
        //获取parentId = 0的根节点
        List<TreeNode> list = trees.stream().filter(item -> item.getParentId() == 0L).collect(Collectors.toList());
        //根据parentId进行分组
        Map<Integer, List<TreeNode>> map = trees.stream().collect(Collectors.groupingBy(TreeNode::getParentId));
        recursionFnTree(list, map);
        return list;
    }


    /**
     * 递归遍历节点
     *
     * @param list
     * @param map
     */
    public static void recursionFnTree(List<TreeNode> list, Map<Integer, List<TreeNode>> map) {
        for (TreeNode treeSelect : list) {
            List<TreeNode> childList = map.get(treeSelect.getId());
            treeSelect.setChildren(childList);
            if (null != childList && 0 < childList.size()) {
                recursionFnTree(childList, map);
            }
        }
    }

    private List<TreeNode> builderTree(List<TreeNode> treeNodes) {
        List<TreeNode> list = new ArrayList<>();
        if (CollectionUtils.isEmpty(treeNodes)) {
            return new ArrayList<>();
        }
        treeNodes.forEach(item -> {
            if (item.getParentId() == 0) {
                list.add(findChild(item, treeNodes));
            }
        });
        return list;
    }

    static TreeNode findChild(TreeNode node, List<TreeNode> list) {
        for (TreeNode n : list) {
            if (n.getParentId() == node.getId()) {
                if (node.getChildren() == null) {
                    node.setChildren(new ArrayList<TreeNode>());
                }
                node.getChildren().add(findChild(n, list));
            }
        }
        return node;
    }


}
